/*
 *	desktop-view view
 *  -----------------------------------------------------------------------------------------------------------
 */

site.view('desktop-view', {
	
	route: '/',
	elementId: '#jtop',
	desktopClass: '.desktop',
	container: null,
	
	onLoad: function(settings) {
		
		var self = this,
			options = {},
			ajax_loader;
		
		options.elements = {elementId: this.elementId, desktopClass: this.desktopClass};

		if(!this.loaded) {

			ajax_loader = this.query('#ajax_loader').fadeIn('slow'); 

			this.request({
				url: '/desktop/index',
				type: 'post',
				dataType: 'json',
				data: {},
				success: function(data) {
					if(data.success === true) {
						options.items = data.items;
						options.edit = data.edit;
						
						self.startAll(options);
						self.trigger('showDesktop');
					}
				},

				complete: function() {
					ajax_loader.hide();
				}
			});
		} else {
			self.trigger('showDesktop');
		}
	},
	
	onUnload: function() {
		this.trigger('hideDesktop');
	}
})

.module('desktop_manager', function(context) {
	
	var query = context.query,
		require = context.require,
		notify = require('notify'),

		desk,
		container,
		desktop,
		dragMode = false,
		cMenuProject,
		cMenuLink,
		tooltip;
	
	actRemove = function(sender) {

		context.setView('remove-item-prompt', {
			itemName: sender.title,
			itemId: sender.ext.item_id,
			success: function() {
				desk.removeItem(sender.id);
				context.trigger('itemRemoved', sender);

				notify.create("create", {
                    title: 'Item removed',
					text: 'Item <b>' + sender.title + '</b> removed from desktop.'
            	}); 
				
			}
		});
	},

	actOpenProject = function(sender) {
		container.stop().fadeOut('normal', function() {
			context.trigger('hideDesktop');
			context.setView('project-view', {id: sender.ext.project_id});
		});
	},

	actPreviewProject = function(sender) {
		container.stop().fadeOut('normal', function() {
			context.trigger('hideDesktop');
			context.setView('project-show-view', {id: sender.ext.project_id});
		});
	},
	
	actOpenLink = function(data) {
		if(data.ext.embed === true) {
			context.setView('desktop-embed-view', data.ext);
		} else {
			context.openWindow(data.ext.link);	
		}
	},

	actEditItem = function(sender) {
		
		var settings = {
			onEdit: function(options) {
				var item = desk.getItemById(sender.id);

				item.attr({
					icon: options.icon,
					title: options.item_title, 
					ext: {
						description: options.item_description, 
					}
				});
			},

			data: {
				id: sender.ext.item_id,
				type: sender.ext.type	
			}
		}

		context.setView('edit-element-modal', settings);
	},

	onShowTooltip = function(ctx, sender) {
		ctx.title.val = sender.title;
		ctx.description.val = sender.ext.description;
		ctx.field.val = sender.ext.field;

		if(util.is(sender.ext.thumbnail, 'string')) {
			ctx.image.val = sender.ext.thumbnail;
		} else {
			ctx.image._visible = false;
		}	
	} 

	createItem = function(options) {

		// first create panel (if exists)
		var panel;
		if(options.panel_id) {
			
			var panelId = 'item_panel_' + options.panel_id;

			panel = desk.getItemById(panelId);

			if(!panel) {
				panel = desk.addItem({
					classes: ['panel'],
					id: panelId,
					x: +options.panel_pos_x, 
					y: +options.panel_pos_y, 
					title: options.panel_title,
					
					ext: {
						id: options.panel_id
					}
					
				});
			}
		}

		var item = desk.addItem({
			x: +options.item_pos_x, 
			y: +options.item_pos_y, 
			icon: options.icon ,
			title: options.item_title, 
			parent: panel ? panel.id : null,
			tooltip: tooltip,
			ext: {
				item_id: options.item_id,
				description: options.item_description, 
				thumbnail: options.thumbnail,
				type: options.type
			}
		});

		if(options.type === 'link') {
			item.menu = cMenuLink;
			item.ext.link = options.link;
			item.ext.embed = options.embed;
			item.ext.field = 'external link';
		} else if (options.type === 'project') {
			item.menu = cMenuProject;
			item.ext.project_id = options.project_id;
			item.ext.field = options.project_field;
		}
	}
 
	return {
		
		init: function(options) {
		
			container = context.query(options.elements.elementId);
			desktop = context.query(options.elements.desktopClass);
			
			desk = context.jtop.desktop({
				edit: options.edit, 
				panelAnimOffsetSpeed: 0, 
				panelAnimOffset: 0,

				CursorIndicator: { enabled: true },
				Tooltip: { enabled: !options.edit }
			});

			cMenuLink = desk.contextMenu({offsetTop: 52 + 25, offsetBottom: 38 - 25, defaultSide: 'down'})
			.addMenuElement('edit item', '', actEditItem) 
			.addMenuElement('open link', '/public/application/images/menuicons/doc.png', actOpenLink) 
			.addMenuElement('remove', '/public/application/images/menuicons/x2.png', actRemove);

			cMenuProject = desk.contextMenu({offsetTop: 52 + 25, offsetBottom: 38 - 25, defaultSide: 'down'})
			.addMenuElement('edit item', '', actEditItem) 
			.addMenuElement('edit project', '/public/application/images/menuicons/doc.png', actOpenProject)
			.addMenuElement('preview project', '/public/application/images/menuicons/preview.png', actPreviewProject) 
			.addMenuElement('remove', '/public/application/images/menuicons/x2.png', actRemove);

			tooltip = desk.tooltip()
			.addElement('title', {orderUp: 1 , orderDown: 0})
			.addElement('description', {orderUp: 2, orderDown: 1})
			.addElement('image',{html: '<img class="image" src="<%=val%>"/>', orderUp: 0, orderDown: 2})
			.addElement('field', {orderUp: 3, orderDown: 3})
			.beforeShow(onShowTooltip);

			// create items
			for (var i = 0, len = options.items.length; i < len; i++) {
				createItem(options.items[i]);
			};
				
			context.trigger('desktopReady', desk);

			container.hide();
		},
		
		destroy: function() {
			desk.unregisterItemAction('actOpenProject');
			desk.unregisterItemAction('actOpenLink');
			desk.unregisterItemAction('actComment');
			desk.clear();
		
			context.trigger('hideDesktop');
		},
		
		events: {
		
			showDesktop: function(options) {
				container.fadeIn(600);
			},
			
			hideDesktop: function() {
				container.fadeOut('normal');
			},
			
			addElement: function() {
				
				var settings = {
					create: function(item_info) {
						
						createItem.call(null, item_info);

						notify.create("create", {
	                        title: 'Item added',
	                        text: 'Item ' + item_info.item_title + ' added.'
                    	}); 
					}
				}
				
				context.setView('add-element-modal', settings);
			}
		}
	}
})

.module('save_layout', function(context) {
	var has = 'hasOwnProperty',
		query = context.query,
		util = context.util,
		request = context.request,
		require = context.require,

		notify = require('notify'),

		topBar,
		btnSaveLayout,
		desktop,
		options,

		processing = false,

		itemsChanged = {};

	function saveItemsLayout() {

		if(processing)
			return;

		processing = true;

		if(Object.keys(itemsChanged).length == 0) {
			itemsLayoutSaved([]);
			return;
		}

		var items = [],
			panels = [];

		// get items to save
		for(var it in itemsChanged) {
			if(!itemsChanged[has](it))
				continue;
			
			var item = itemsChanged[it];

			if(item.type === 'default') {
				items.push({id: item.ref.ext.item_id, pos_x : item.ref.x, pos_y: item.ref.y, panel_ref_id: item.ref.parent});

			} else if(item.type === 'panel') {
				panels.push({
					state: item.state,												// can be new|update|delete
					ref_id: item.ref.id,											// panel ref id on desktop
					id: (item.ref.ext && item.ref.ext.id) ? item.ref.ext.id : 0,	// real id, otherwise 0 (for new event)
					title: item.ref.title,
					pos_x: item.ref.x,
					pos_y: item.ref.y,
					width: item.ref.width,
					height: item.ref.height,
					columns: item.ref.getItems().length,
					rows: 1
				});

			}
		}

		var request_data = {
			panels: panels,
			items: items
		}

		request({					
			url: '/desktop/update_layout',
			dataType: 'json',
			type: "post",
			data: request_data,

			success: function(data) {
				if(data.success === true) {
					itemsLayoutSaved(data.content);

					notify.create("create", {
                        title: data.message,
                        text: data.description
                    }); 
				} else {
					var err_msg = '';
						
					util.eachRecursive(data.errors, function(key, val) {
						err_msg += err_msg === '' ? val : '<br/>' + val;
					});
					
					notify.create('create','error-template', {
						title: data.message,
						text: err_msg
					});
				}
			},

			error: function(err) {
				notify.create('create','error-template', {
					title: 'Error',
					text: 'Cannot save layout. Service unavailable.'
				});
			},

			complete: function() {
				processing = false;
			}
		});
	};

	function itemsLayoutSaved(items) {
		itemsChanged = [];
		btnSaveLayout.fadeOut();

		// set panel ids
		for(var i = 0, len = items.length; i < len; i++) {
			var item = items[i],
				panel = desktop.getItemById(item.panel_ref_id); 

			if(panel) {
				panel.ext = {
					id : items[i].panel_id
				}
			}
		}
	};

	function itemAttrChange(item) {
		
		if(!itemsChanged[has](item.ref.id)) {
			
			itemsChanged[item.ref.id] = {
				state: 'update',
				type: item.ref.classes[0],
				ref: item.ref
			};
		}

		if(!btnSaveLayout.is(':visible')) {
			btnSaveLayout.fadeIn(200);
		}	
	};

	function panelAttrChange(panel) {

		if(!itemsChanged[has](panel.ref.id)) {
			
			itemsChanged[panel.ref.id] = {
				state: 'update',
				type: panel.ref.classes[0],
				ref: panel.ref
			};

			var panelItems = panel.ref.getItems();

			for (var i = panelItems.length - 1; i >= 0; i--) {
				
				var item = panelItems[i];
				
				if(!itemsChanged[has](item.id)) {
					
					itemsChanged[item.id] = {
						state: 'update',
						type: item.classes[0],
						ref: item
					};
				}
			};
		}

		if(!btnSaveLayout.is(':visible')) {
			btnSaveLayout.show();
		}	
	};

	function panelRemoved(panel) {
		if(panel.ref.ext && panel.ref.ext.id) {					// panel is saved
			
			itemsChanged[panel.ref.id] = {
				state: 'delete',
				type: panel.ref.classes[0],
				ref: util.extend({}, panel.ref)
			};

		} else if (itemsChanged[has](panel.ref.id) && itemsChanged[panel.ref.id].state === 'new') {	// panel is not saved - remove from list
			itemsChanged[panel.ref.id] = undefined;
			delete itemsChanged[panel.ref.id];
		}
	};

	function panelAdded(panel) {
		if(!itemsChanged[has](panel.ref.id)) {
			itemsChanged[panel.ref.id] = {
				state: 'new',
				type: panel.ref.classes[0],
				ref: panel.ref
			};

			var panelItems = panel.ref.getItems();

			for (var i = panelItems.length - 1; i >= 0; i--) {
				
				var item = panelItems[i];
				
				if(!itemsChanged[has](item.id)) {
					
					itemsChanged[item.id] = {
						state: 'update',
						type: item.classes[0],
						ref: item
					};
				}
			};
		}
	};
	
	return {
		init: function(options) {

			// event listener to change item attributes
			if (options.edit === true) {
				topBar = query('header');
				btnSaveLayout = query('<a href="#" class="desktop_save_button button_blue">save changes</a>');
				btnSaveLayout.hide();
				topBar.append(btnSaveLayout);                         
				btnSaveLayout.bind('click', saveItemsLayout);
			}
		},

		destroy: function() {
			if (options.edit === true) {
				btnSaveLayout.unbind('click', saveItemsLayout);
				btnSaveLayout.remove();
			}
		},

		events: {
			desktopReady: function(desk) {
				if (desk.attr('edit') === true) {
					desktop = desk;
					desktop.addEventListener('itemDragStart', itemAttrChange);
					desktop.addEventListener('panelItemPosChanged', itemAttrChange);
					desktop.addEventListener('panelDragStart', panelAttrChange);
					desktop.addEventListener('addedItemToPanel', panelAttrChange);
					desktop.addEventListener('removedItemFromPanel', panelAttrChange);
					desktop.addEventListener('removePanelItem', panelRemoved);
					desktop.addEventListener('addPanelItem', panelAdded);

				}
			},

			itemRemoved: function(item) {

				if(itemsChanged[has](item.id)) {
					itemsChanged[item.id] = null;
					delete itemsChanged[item.id];
				}

				saveItemsLayout();
			}
		}
	}
})

.module('profile_navigation', function(context) {
	
	var navigation = context.query('ul','nav.profile_navigation'),
	actions = [];
	
	function createNavigationAction(id, href, callback) {
		var a = context.createElement('a'),
		li = context.createElement('li');
		a.setAttribute('id', id);
		a.setAttribute('href', href);
		
		li.appendChild(a);
		
		if(typeof(callback) === 'function') {
			context.query(a).click(function() {
				callback.call(null);
				return false;
			});
		}
		
		actions.push(id);
		navigation.append(li);
		
	};
	
	function removeNavigationActions() {
		for(var i = 0, len = actions.length; i < len; i++) {
			navigation.find('#' + actions[i]).parent().remove();
		}
	};
	
	function showNavigationActions() {
		for(var i = 0, len = actions.length; i < len; i++) {
			navigation.find('#' + actions[i]).show();
		}
	};
	
	function hideNavigationActions() {
		for(var i = 0, len = actions.length; i < len; i++) {
			navigation.find('#' + actions[i]).hide();
		}
	};
	
	return {
		
		init: function(options) {

			if(options.edit === true) {
				createNavigationAction('add_element_icon_mini', '/public/desktop/addelement', function() {
					context.trigger('addElement');
				});
			}
		},
		
		destroy: function() {
			removeNavigationActions();
		},
		
		events: {
			
			showDesktop: function() {
				showNavigationActions();
			},
			
			hideDesktop: function() {
				hideNavigationActions();
			}
		}
	}
});